#include <iostream>
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;

vector<Vec2f> hough_lines;
vector<Vec4i> hough_lines_p;
Mat hough_dst, hough_cdst, hough_cdst_p;
int hough_threshold1 = 200;

Mat hough_dst_circle;

static void hough_onThresholdChanged(int, void*);

int hough()
{
	Mat src = imread("resources/building.jpg", 0);
	Mat src_circle = imread("resources/circle.jpg");
	if (src.empty())
	{
		cout << "image load failed" << endl;
		return -1;
	}

	Canny(src, hough_dst, 50, 200);

	cvtColor(src_circle, hough_dst_circle, CV_BGR2GRAY);
	GaussianBlur(hough_dst_circle, hough_dst_circle, Size(9, 9), 2, 2);

	vector<Vec3f> circles;

	/// Apply the Hough Transform to find the circles
	HoughCircles(hough_dst_circle, circles, CV_HOUGH_GRADIENT, 1, hough_dst_circle.rows / 8, 100, 100, 0, 0);

	/// Draw the circles detected
	for (size_t i = 0; i < circles.size(); i++)
	{
		Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
		int radius = cvRound(circles[i][2]);
		// circle center
		circle(src_circle, center, 3, Scalar(0, 255, 0), -1, 8, 0);
		// circle outline
		circle(src_circle, center, radius, Scalar(0, 0, 255), 3, 8, 0);
	}

	namedWindow("dst");
	imshow("src_circle", src_circle);

	createTrackbar("threshold", "dst", &hough_threshold1, 500, hough_onThresholdChanged);

	hough_onThresholdChanged(0, 0);

	waitKey(0);

	return 0;
}

static void hough_onThresholdChanged(int, void*)
{
	cvtColor(hough_dst, hough_cdst, CV_GRAY2BGR);
	hough_cdst.copyTo(hough_cdst_p);

	HoughLines(hough_dst, hough_lines, 1, CV_PI / 180, hough_threshold1);
	HoughLinesP(hough_dst, hough_lines_p, 1, CV_PI / 180, hough_threshold1);

	for (size_t i = 0; i < hough_lines.size(); i++)
	{
		float rho = hough_lines[i][0], theta = hough_lines[i][1];
		Point pt1, pt2;
		double a = cos(theta), b = sin(theta);
		double x0 = a*rho, y0 = b*rho;
		pt1.x = cvRound(x0 + 1000 * (-b));
		pt1.y = cvRound(y0 + 1000 * (a));
		pt2.x = cvRound(x0 - 1000 * (-b));
		pt2.y = cvRound(y0 - 1000 * (a));
		line(hough_cdst, pt1, pt2, Scalar(0, 0, 255), 1, CV_AA);
	}

	for (size_t i = 0; i < hough_lines_p.size(); i++)
	{
		Vec4i l = hough_lines_p[i];
		line(hough_cdst_p, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0, 0, 255), 1, CV_AA);
	}

	imshow("dst", hough_dst);
	imshow("cdst", hough_cdst);
	imshow("cdst_p", hough_cdst_p);
}